package com.weixing.mall.util.number;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;

@Slf4j
public class NumberToRmbUtil {

    private static final String[] RMB_ARR = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    private static final String[] UNIT_ARR = {"", "十", "佰", "仟"};
    private static final String[] HIGH_UINIT_ARR = {"", "万", "亿"};
    private static final String[] LOW_UNIT_ARR = {"角", "分"};
    private static final String RMB_UNIT = "元";
    private static final String RMB_INTEGER = "整";
    private static final String ZERO_STR = "0";
    private static final String DOUBLE_ZERO_STR = "00";
    private static final char ZERO_CHR = '0';
    private static final int SCALE = 0;
   /**
    * 数字最大长度
   */
    private static final int MAX_AMOUNT_LIMIT = 1000000000;

    private NumberToRmbUtil() {
        throw new IllegalStateException("Utility class");
    }


    /**
     * 方法描述: 金额格式化
     * @Author Small
     * @param amount      要格式化的金额
     * @Date 2020/3/19 14:43
     * @return java.lang.String
     */
    public static  String defaultFormat(BigDecimal amount){
        return format(amount,NumberPatternEnum.PAT_DEFAULT.getValue());
    }



    /**
     * 方法描述: 金额格式化
     * @Author Small
     * @param amount      要格式化的金额
     * @param fmtPattern  要转换的格式
     * @Date 2020/3/19 14:43
     * @return java.lang.String
    */
    public static  String format(BigDecimal amount,String fmtPattern){
		DecimalFormat decimalFormat = new DecimalFormat(fmtPattern);
		return decimalFormat.format(amount);
	}



    /**
     * BigDecimal类型数据取整数并转为字符串
     */
    private static String greaterZeroToInt(BigDecimal amount) {
        if (amount == null) {
            return ZERO_STR;
        }
        return amount.divide(new BigDecimal(1), SCALE, RoundingMode.DOWN).toString();
    }

    /**
     * BigDecimal类型数据取整数
     */
    private static BigDecimal greaterZeroNum(BigDecimal amount) {
        return amount.divide(new BigDecimal(1), SCALE, RoundingMode.DOWN);
    }

    /**
     * BigDecimal类型数据取2位小数转为字符串整数，不足2位十位补0
     */
    private static String lessZeroToInt(BigDecimal amount) {
        String intStr = amount.movePointRight(2).divide(new BigDecimal(1), SCALE, RoundingMode.HALF_UP).toBigInteger()
                .toString();
        if (intStr.length() == 1) {
            return ZERO_STR + intStr;
        }
        return intStr;
    }

    /**
     * 整数转人民币
     */
    private static String itoRmbStr(String numStr) {
        StringBuilder result = new StringBuilder();
        if (ZERO_STR.equals(numStr)) {
            return result.toString();
        }
        int len = numStr.length();
		Assert.isTrue(len > MAX_AMOUNT_LIMIT,"数字长度超过系统限制");
        int col = (len - 1) / 4;
        int row = (len - 1) % 4;
        int index = 0;
        for (int i = 0; i <= col; i++) {
            for (int j = 0; j <= row; j++) {
                if (numStr.charAt(index) == ZERO_CHR) {
                    if ((numStr.charAt(index - 1) == ZERO_CHR && j != 0) || j == row) {
                        index++;
                        continue;
                    }
                    result.append(RMB_ARR[numStr.charAt(index) - ZERO_CHR]);
                } else {
                    result.append(RMB_ARR[numStr.charAt(index) - ZERO_CHR]);
                    result.append(UNIT_ARR[row - j]);
                }
                index++;
            }
            result.append(HIGH_UINIT_ARR[col - i]);
            row = 3;
        }
        result.append(RMB_UNIT);
        return result.toString();
    }

    /**
     * 小数转人民币
     */
    private static String ftoRmbStr(String numStr) {
        String result = "";
        if (numStr.equals(DOUBLE_ZERO_STR) || numStr.equals(ZERO_STR)) {
            return RMB_INTEGER;

        }
        result += RMB_ARR[numStr.charAt(0) - ZERO_CHR];
        if (numStr.charAt(0) != ZERO_CHR) {
            result += LOW_UNIT_ARR[0];
        }
        result += RMB_ARR[numStr.charAt(1) - ZERO_CHR];
        if (numStr.charAt(1) != ZERO_CHR) {
            result += LOW_UNIT_ARR[1];
        }
        return result;
    }

    /**
     * 数字转人民币
     */
    public static String change(BigDecimal amount) {
        validAmount(amount);
        String greaterZeroToInt = greaterZeroToInt(amount);
        String itoRmbStr = itoRmbStr(greaterZeroToInt);
        BigDecimal lessZeroNum = amount.subtract(greaterZeroNum(amount));
        String lessZeroToInt = lessZeroToInt(lessZeroNum);
        String ftoRmbStr = ftoRmbStr(lessZeroToInt);
        return itoRmbStr + ftoRmbStr;
    }

    /**
     * 格式化人名币数字为￥12,343,171.60类似格式(带小数位)
     */
    public static String formatYuan(BigDecimal amount) {
        return formatNumber(amount, 2, 4);
    }

    /**
     * 格式化人名币数字为￥12,343,171类似格式(不带小数位)
     */
    public static String formatFen(BigDecimal amount) {
        return formatNumber(amount, 0, 0);
    }

    /**
     * 格式化人名币数字为￥12343171类似格式(不带小数位且不带分隔符)
     */
    public static String formatFenNoSymbol(BigDecimal amount) {
        return formatFen(amount).replace(",", "");
    }

    /**
     *  格式化人名币数字
     * @function formatNumber
     * @param amount 金额
     * @param minDigits 设置数的小数部分所允许的最小位数(如果不足后面补0)
     * @param maxDigits 设置数的小数部分所允许的最大位数(如果超过会四舍五入)
     * @return String
     *
     */
    private static String formatNumber(BigDecimal amount, int minDigits, int maxDigits) {
        validAmount(amount);
        NumberFormat currency = NumberFormat.getCurrencyInstance();
        currency.setMinimumFractionDigits(minDigits);
        currency.setMaximumFractionDigits(maxDigits);
        return currency.format(amount);
    }

    private static void validAmount(BigDecimal amount) {
    	Assert.isNull(amount,"数字不可为null");
    }


    public static void main(String[] args) {
        BigDecimal amount = new BigDecimal("0.5");
        String format = format(amount, NumberPatternEnum.PAT_DEFAULT.getValue());
        System.out.println(format);
    }

}